Previous Book Contents Book Index Next

Inside Macintosh: 3D Graphics Programming With QuickDraw 3D /
Chapter 17 - File Objects


Using File Objects

You use file objects to read 3DMF data from or write 3DMF data to a storage object, which represents a physical storage device available on a computer. Before you can access 3DMF data in a piece of storage, however, you need to create a storage object to represent the physical storage device, create a file object, and attach the file object to the storage object. This section describes how to perform these tasks.

Creating a File Object

To access the data in a piece of storage that conforms to the 3DMF standard (such as a file on disk or a block of memory on the Clipboard), you need to create a new storage object, create a new file object, and attach the file object to the storage object. Thereafter, you can open the file object and read the data in it or write data to it. Listing 17-1 illustrates how to create storage and file objects and attach them to one another.

The MyGetInputFile function defined in Listing 17-1 calls the application-
defined routine MyGetInputFileName to get the name of the disk file to open. Then it calls Q3FSSpecStorage_New to create a new storage object associated with that disk file and Q3File_New to create a new file object. If both creation calls complete successfully, MyGetInputFile calls Q3File_SetStorage to attach the file object to the storage object.

Note
See the chapter "Storage Objects" for complete
details on creating storage objects.
Listing 17-1 Creating a new file object

TQ3FileObject MyGetInputFile (void)
{
   TQ3FileObject     myFileObj;
   TQ3StorageObject  myStorageObj;
   FSSpec            myFSSpec;

   if (MyGetInputFileName(&myFSSpec) == kQ3False)
      return(NULL);

   /*Create new storage object and new file object.*/
   if(((myStorageObj = Q3FSSpecStorage_New(&myFSSpec)) == NULL) 
      || ((myFileObj = Q3File_New()) == NULL)) 
   {
      if (myStorageObj) 
         Q3Object_Dispose(myStorageObj);
      return(NULL);
   }

   /*Set the storage for the file object.*/
   Q3File_SetStorage(myFileObj, myStorageObj);
   Q3Object_Dispose(myStorageObj);

   return (myFileObj);
}
Notice that the call to Q3File_SetStorage is followed immediately by a call to Q3Object_Dispose. The call to Q3File_SetStorage increases the reference count of the storage object, and the call to Q3Object_Dispose simply decreases that count.

Reading Data from a File Object

The data in an 3DMF file is organized into discrete units called metafile objects (or, more briefly, and despite the risk of confusion with QuickDraw 3D objects, objects). You read data from an 3DMF file by reading each individual metafile object in it (by calling the Q3File_ReadObject function), until you reach the end of the file. Listing 17-2 illustrates how to read the metafile objects in an 3DMF file.

The MyRead3DMFModel function defined in Listing 17-2 opens a file object and sequentially reads each metafile object in the 3DMF file into a QuickDraw 3D object. MyRead3DMFModel determines the type of the QuickDraw 3D object read. If the object is a view hints object, MyRead3DMFModel returns that object in the viewHints parameter. If the object isn't a view object, it must be some other drawable QuickDraw 3D object. In that case, MyRead3DMFModel either returns that object in the model parameter (if there are no more objects in the 3DMF file) or adds it to a display group. When it executes successfully, MyRead3DMFModel returns both a 3D model and a view hints object to its caller.

Listing 17-2 Reading metafile objects

TQ3Status MyRead3DMFModel 
               (TQ3FileObject file, TQ3Object *model, TQ3Object *viewHints)
{
   TQ3Object      myGroup;
   TQ3Object      myObject;

   /*Initialize view hints and model to be returned.*/
   *viewHints = NULL;
   *model = NULL;
   myGroup = NULL;
   myObject = NULL;

   /*Open the file object and exit gracefully if unsuccessful.*/
   if (Q3File_OpenRead(file, NULL) != kQ3Success)
   {
      DoError("MyRead3DMFModel", "Reading failed %s", filename);
      return kQ3Failure;
   }

   while (Q3File_IsEndOfFile(file) == kQ3False)
   {
      myObject = NULL;
      /*Read a metafile object from the file object.*/
      myObject = Q3File_ReadObject(file);
      if (myObject == NULL)
         continue;

      /*Save a view hints object, and add any drawable objects to a group.*/
      if (Q3Object_IsType(myObject, kQ3SharedTypeViewHints))
      {
         if (*viewHints == NULL)
         {
            *viewHints = myObject;
            myObject = NULL;
         }
      }
      else if (Q3Object_IsDrawable(myObject))
      {
         if (myGroup)
         {
            Q3Group_AddObject(myGroup, myObject);
         }
         else if (*model == NULL)
         {
            *model = myObject;
            myObject = NULL;
         }
         else
         {
            myGroup = Q3DisplayGroup_New();
            Q3Group_AddObject(myGroup, *model);
            Q3Group_AddObject(myGroup, myObject);
            Q3Object_Dispose(*model);
            *model = myGroup;
         }
      }
      if (myObject != NULL) 
         Q3Object_Dispose(myObject);
   }
   
   if (Q3Error_Get(NULL) != kQ3ErrorNone)
   {
      if (*model != NULL) {
         Q3Object_Dispose(*model); 
         *model = NULL; 
      }
   
      if (*viewHints != NULL) {
         Q3Object_Dispose(*viewHints); 
         *viewHints = NULL; 
      }
      return (kQ3Failure);
   }
 return kQ3Success;
}

Writing Data to a File Object

To write a model or other 3D data into a file conforming to the QuickDraw 3D Object Metafile format, you can use submit calls (such as Q3Object_Submit) with an open file object that is attached to a storage object. Depending on the complexity of the model and the amount of available memory, QuickDraw 3D might need to traverse the model more than once to write the data to the target physical storage device. Accordingly, you should perform all write operations within a writing loop, bracketed by calls to Q3View_StartWriting and Q3View_EndWriting. Listing 17-3 illustrates a simple writing loop.

Listing 17-3 Writing 3D data to a file object

Q3View_StartWriting(myView, myFileObj);
do {
   Q3Object_Submit(myModel, myView);
   Q3Polyline_Submit(&myAnimatedData, myView);
   Q3TriGrid_Submit(&myBumpExtrapolationGrid, myView);
} while (Q3View_EndWriting(myView) == kQ3ViewStatusRetraverse);

Previous Book Contents Book Index Next

© Apple Computer, Inc.
11 JUL 1996